//#include <iostream>
#include "xmlparse.h"

XMLParse::XMLParse(QString spr_name)
{
spreadsheet = spr_name;
metatag = false;
elements = 0;
selected_sheet = false;
}

XMLParse::~XMLParse()
{
}


bool XMLParse::startElement( const QString & ns,
                             const QString & localName,
                             const QString & qName,
                             const QXmlAttributes & attributes )
{
    if ( !metatag && true != qName.contains("Workbook") )
    {
    errorStr = QObject::tr("The file is not a MS XML Speadsheet file.");
    return false;
    }

    if ( qName == "Workbook" ||
         localName == "Workbook" )
    {
    metatag = true;
    }

    if ( ns != "urn:schemas-microsoft-com:office:spreadsheet" )
    {
    return true;
    }

    if ( qName == "Worksheet" ||
         localName == "Worksheet" )
    {
        if ( ( attributes.value("ss:Name").isNull() ||
               attributes.value("ss:Name").isEmpty() )
            &&
             ( attributes.value("Name").isNull() ||
               attributes.value("Name").isEmpty() ) )
        {
        selected_sheet = false;
        return false;
        }
        
        if ( spreadsheet == attributes.value("ss:Name") ||
             spreadsheet == attributes.value("Name") )
        {
        selected_sheet = true;
        }
        else
        {
        selected_sheet = false;
        }
    }
    else if ( qName == "Row" ||
              localName == "Row" )
    {
        if (true != selected_sheet)
        {
        return true;
        }
    
    m.clear();
    elements = 0;
    }
    else if ( qName == "Cell" ||
              localName == "Cell" )
    {
        if (true != selected_sheet)
        {
        return true;
        }

        if (!attributes.value("ss:Index").isNull() &&
            !attributes.value("ss:Index").isEmpty() )
        {
        bool ok = false;
        int idx = attributes.value("ss:Index").toInt(&ok, 10);
           if (true == ok)
           {
           elements = idx;
           }
           else
           {
           //std::cout << "Error at index convertion." << std::endl;
           return false;
           }
        }
        else if (!attributes.value("Index").isNull() &&
                 !attributes.value("Index").isEmpty() )
        {
        bool ok = false;
        int idx = attributes.value("Index").toInt(&ok, 10);
           if (true == ok)
           {
           elements = idx;
           }
           else
           {
           //std::cout << "Error at index convertion." << std::endl;
           return false;
           }

        }
        else
        {
        elements += 1;
        }
    }

currentText.clear();
return true;
}

bool XMLParse::endElement( const QString & ns,
                           const QString & localName,
                           const QString & qName )
{
    if ( ns != "urn:schemas-microsoft-com:office:spreadsheet" )
    {
    return true;
    }

    if ( qName == "Worksheet" ||
         localName == "Worksheet" )
    {
        if (true == selected_sheet)
        {
        selected_sheet = false;
        }
    }
    else if ( qName == "Row" ||
              localName == "Row" )
    {
        if (true != selected_sheet)
        {
        return true;
        }

        if ( true != m.isEmpty() )
        {
        d.push_back(m);
        }
    }
    else if ( qName == "Data" ||
              localName == "Data" )
    {
        if (true != selected_sheet)
        {
        return true;
        }    
        else
        {
        m.insert(elements, currentText);
        }
    }
return true;
}

bool XMLParse::characters(const QString &str)
{
currentText += str;
return true;
}

bool XMLParse::fatalError(const QXmlParseException &exception)
{
errorStr = QObject::tr( "Parse error at line %1, column %2:\n %3")
                          .arg(exception.lineNumber())
                          .arg(exception.columnNumber())
                          .arg(exception.message() );
return false;
}

QString XMLParse::errorString() const
{
return errorStr;
}

QList< QMap<int,QString> > XMLParse::return_data()
{
return d;
}
